﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using devtm.Aop.Event;
using System.Reflection;

namespace devtm.Aop.Behavior
{

    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
    public abstract class InterceptMethodAttribute : InterceptAttribute, devtm.Aop.Event.IInterceptMethod
    {


        public InterceptMethodAttribute()
        {

        }



        /// <summary>
        /// Called when [entry].
        /// Method injected in the intercepted method
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="devtm.Aop.Event.InterceptEventArgs"/> instance containing the event data.</param>
        /// <param name="context">The context.</param>
        [System.Diagnostics.DebuggerStepThrough]
        [InterceptEventAttribute(InterceptEnumEventType.BeforeCall)]
        public virtual void OnEntry(object sender, InterceptEventArgs args, int context)
        {
            try
            {
                args.Context = context;
                EntryMethod(sender, args);
            }
            catch (Exception e)
            {

                if (e is InjectionException)
                    throw e;

                else
                    InterceptAttribute.Error(args, e);

            }
            

        }



        /// <summary>
        /// Called when [exit].
        /// Method injected in the intercepted method
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="devtm.Aop.Event.InterceptEventArgs"/> instance containing the event data.</param>
        /// <param name="context">The context.</param>
        [System.Diagnostics.DebuggerStepThrough]
        [InterceptEventAttribute(InterceptEnumEventType.AfterCall)]
        public virtual void OnExit(object sender, InterceptEventArgs args, int context)
        {
            try
            {
                args.Context = context;
                ExitMethod(sender, args);
            }
            catch (Exception e)
            {
                InterceptAttribute.Error(args, e);
            }
            
          
        }


        public abstract void EntryMethod(object sender, InterceptEventArgs args);

        public abstract void ExitMethod(object sender, InterceptEventArgs args);


    }


}
